/**
 * @file    threads_pool.c
 * @brief   线程池模块实现文件
 * 
 * @details 实现了线程池的核心功能，包括线程管理、任务调度、资源清理等
 * 
 * @author  连佳炜
 * @date    2025-09-12
 */

#ifndef __THREADS_POOL_C__
#define __THREADS_POOL_C__

#include <threads_pool.h>


/**
 * @brief       清理处理函数
 * @details     线程取消时自动调用的清理函数，用于确保互斥锁被正确释放
 * 
 * @param[in]   arg 互斥锁指针
 * 
 * @note        此函数由pthread_cleanup_push/pop机制自动调用
 */
static inline void cleanUpHandle (
    void* arg   /**< 函数参数（互斥锁地址） */
)
{
    // 互斥锁地址
    pthread_mutex_t* mtxUnPt;

    // 初始化互斥锁地址
    mtxUnPt = (pthread_mutex_t*)arg;

    // 解锁
    pthread_mutex_unlock(mtxUnPt);    
}

/**
 * @brief       创建新的任务信息
 * @details     分配并初始化一个新的任务信息结构体
 * 
 * @param[in]   handleFuncPt    任务处理函数指针
 * @param[in]   handleFuncArg   任务处理函数参数
 * 
 * @return      成功返回任务信息指针，失败返回NULL
 * 
 * @note        返回的任务信息需要手动释放内存
 */
static inline TaskMsg_st_pt getNewTaskMsg (
    void* (* handleFuncPt)(void* arg),  /**< 处理函数地址 */
    void* handleFuncArg                 /**< 处理函数参数 */
)
{
    // 新任务信息地址
    TaskMsg_st_pt newTaskMsgStPt;

    // 分配新任务信息内存
    newTaskMsgStPt = malloc(sizeof(TaskMsg_st));

    // 初始化新任务信息
    newTaskMsgStPt->handleFuncPt = handleFuncPt;
    newTaskMsgStPt->handleFuncArg = handleFuncArg;
    newTaskMsgStPt->prevTaskMsgStPt = newTaskMsgStPt;
    newTaskMsgStPt->nextTaskMsgStPt = newTaskMsgStPt;

    return newTaskMsgStPt;
}

/**
 * @brief       将新任务信息加入队列
 * @details     将任务信息添加到任务队列的尾部
 * 
 * @param[in]   trdsPolMsgStPt   线程池指针
 * @param[in]   newTaskMsgStPt   新任务信息指针
 * 
 * @note        此函数假设调用者已持有线程池锁
 */
static inline void inqueueNewTaskMsg (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt,    /**< 线程池地址 */
    TaskMsg_st_pt newTaskMsgStPt            /**< 新任务信息地址 */
)
{
    // 更新新任务信息
    newTaskMsgStPt->prevTaskMsgStPt = trdsPolMsgStPt->tasksLinkedQueueEntr->prevTaskMsgStPt;
    newTaskMsgStPt->nextTaskMsgStPt = trdsPolMsgStPt->tasksLinkedQueueEntr;
    // 更新线程池
    trdsPolMsgStPt->tasksLinkedQueueEntr->prevTaskMsgStPt->nextTaskMsgStPt = newTaskMsgStPt;
    trdsPolMsgStPt->tasksLinkedQueueEntr->prevTaskMsgStPt = newTaskMsgStPt;
    trdsPolMsgStPt->waitingTasksCot ++;
}

/**
 * @brief       从队列中取出任务信息
 * @details     从任务队列的头部取出一个任务信息
 * 
 * @param[in]   trdsPolMsgStPt 线程池指针
 * 
 * @return      取出的任务信息指针
 * 
 * @note        此函数假设调用者已持有线程池锁
 */
static inline TaskMsg_st_pt dequeueTaskMsg (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt /**< 线程池地址 */
)
{
    // 任务链队头地址
    TaskMsg_st_pt tasksHeadStPt;

    // 初始化任务链队头地址
    tasksHeadStPt = trdsPolMsgStPt->tasksLinkedQueueEntr->nextTaskMsgStPt;
    // 更新线程池
    trdsPolMsgStPt->tasksLinkedQueueEntr->nextTaskMsgStPt = tasksHeadStPt->nextTaskMsgStPt;
    tasksHeadStPt->nextTaskMsgStPt->prevTaskMsgStPt = trdsPolMsgStPt->tasksLinkedQueueEntr;
    trdsPolMsgStPt->waitingTasksCot --;
    // 更新任务链队头
    tasksHeadStPt->prevTaskMsgStPt = tasksHeadStPt;
    tasksHeadStPt->nextTaskMsgStPt = tasksHeadStPt;

    return tasksHeadStPt;
}

/**
 * @brief       移除指定任务信息
 * @details     从任务队列中移除指定处理函数的任务信息
 * 
 * @param[in]   trdsPolMsgStPt     线程池指针
 * @param[in]   destHandleFuncPt   目标处理函数指针
 * 
 * @return      成功找到并移除返回0，未找到返回-1
 * 
 * @note        此函数假设调用者已持有线程池锁
 */
static inline int removeDestTaskMsg (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt,    /**< 线程池地址 */
    void* (* destHandleFuncPt)(void* arg)   /**< 目标处理函数地址 */
)
{
    // 删除标志
    int rmFlag;
    // 目标任务信息地址
    TaskMsg_st_pt destTaskMsgStPt;

    // 初始化删除标志
    rmFlag = -1;
    // 初始化目标任务信息地址
    for (
        destTaskMsgStPt = trdsPolMsgStPt->tasksLinkedQueueEntr->nextTaskMsgStPt;
        destTaskMsgStPt != trdsPolMsgStPt->tasksLinkedQueueEntr;
        destTaskMsgStPt = destTaskMsgStPt->nextTaskMsgStPt
    )
    {
        if (destTaskMsgStPt->handleFuncPt == destHandleFuncPt)
        {
            // 更新线程池
            destTaskMsgStPt->prevTaskMsgStPt->nextTaskMsgStPt = destTaskMsgStPt->nextTaskMsgStPt;
            destTaskMsgStPt->nextTaskMsgStPt->prevTaskMsgStPt = destTaskMsgStPt->prevTaskMsgStPt;
            trdsPolMsgStPt->waitingTasksCot --;
            // 更新目标任务信息
            destTaskMsgStPt->handleFuncPt = NULL;
            destTaskMsgStPt->handleFuncArg = NULL;
            destTaskMsgStPt->prevTaskMsgStPt = destTaskMsgStPt;
            destTaskMsgStPt->nextTaskMsgStPt = destTaskMsgStPt;
            // 释放目标任务信息内存
            free(destTaskMsgStPt);
            // 更新删除标志
            rmFlag = 0;
            break;
        }
    }

    return rmFlag;
}

/**
 * @brief       线程例程函数
 * @details     工作线程的主循环函数，从任务队列获取任务并执行
 * 
 * @param[in]   arg 线程参数（线程池指针）
 * 
 * @return      线程退出状态
 * 
 * @note        此函数会一直运行直到线程池关闭
 */
static inline void* threadRoutine (
    void* arg   /**< 例程参数（线程池信息地址） */
)
{
    // 线程池信息地址
    ThreadsPoolMsg_st_pt trdsPolMsgStPt;

    // 初始化线程池信息地址
    trdsPolMsgStPt = (ThreadsPoolMsg_st_pt)arg;
    // 任务信息地址
    TaskMsg_st_pt taskMsgStPt;

    while (1) 
    {
        /* +++++++++++++++++++ 压栈预清理函数并加锁 +++++++++++++++++++ */
        READY_CLEAN_UP_AND_LOCK(cleanUpHandle, &trdsPolMsgStPt->mtxUn);
        /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
        // 注意: 
        // 一定要为等待条件加一个用来判断线程池是否启动销毁的条件判断，
        // 否则即使线程池启动销毁，也会因为无任务继续等待导致一直阻塞在接合的过程，无法退出
        while (trdsPolMsgStPt->waitingTasksCot == 0 && trdsPolMsgStPt->shutDown == false)
        {
            // 无等待任务，且线程池未启动销毁，等待新任务
            pthread_cond_wait(&trdsPolMsgStPt->codUn, &trdsPolMsgStPt->mtxUn);
        }
        if (trdsPolMsgStPt->shutDown == true && trdsPolMsgStPt->waitingTasksCot == 0)
        {
            // 线程池启动销毁且没有待处理任务，退出线程
            pthread_mutex_unlock(&trdsPolMsgStPt->mtxUn);
            pthread_exit(NULL);
        }
        // 出队任务信息
        taskMsgStPt = dequeueTaskMsg(trdsPolMsgStPt);
        /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
        UNLOCK_AND_CANCEL_CLEAN_UP(&trdsPolMsgStPt->mtxUn);
        /* +++++++++++++++++++ 解锁并出栈预清理函数 +++++++++++++++++++ */
        // 禁用线程取消功能
        pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
        // 执行任务
        taskMsgStPt->handleFuncPt(taskMsgStPt->handleFuncArg);
        // 启用线程取消功能
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
        // 释放执行完毕的任务信息内存
        free(taskMsgStPt);
    }

    // 退出线程
    pthread_exit(NULL);
}

/**
 * @brief       创建新的线程信息
 * @details     分配并初始化一个新的线程信息结构体
 * 
 * @param[in]   trdsPolMsgStPt 线程池指针
 * 
 * @return      成功返回线程信息指针，失败返回NULL
 * 
 * @note        如果线程池指针不为NULL，会创建并启动新线程
 */
static inline ThreadMsg_st_pt getNewThreadMsg (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt /**< 线程池信息地址 */
)
{
    // 新线程信息地址
    ThreadMsg_st_pt newTrdMsgStPt;

    // 分配新线程信息内存
    newTrdMsgStPt = malloc(sizeof(ThreadMsg_st));

    // 初始化新线程信息
    if (trdsPolMsgStPt != NULL)
    {
        // 非创建入口
        pthread_create(&newTrdMsgStPt->tid, NULL, threadRoutine, (void*)trdsPolMsgStPt);
    }
    newTrdMsgStPt->prevTrdMsgStPt = newTrdMsgStPt;
    newTrdMsgStPt->nextTrdMsgStPt = newTrdMsgStPt;

    return newTrdMsgStPt;
}

/**
 * @brief       插入新线程信息到链表
 * @details     将线程信息添加到线程链表的尾部
 * 
 * @param[in]   trdsPolMsgStPt   线程池指针
 * @param[in]   newTrdMsgStPt    新线程信息指针
 * 
 * @note        此函数假设调用者已持有线程池锁
 */
static inline void insertNewThreadMsg (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt,    /**< 线程池信息地址 */
    ThreadMsg_st_pt newTrdMsgStPt           /**< 新线程信息地址 */
)
{
    // 更新新线程信息
    newTrdMsgStPt->prevTrdMsgStPt = trdsPolMsgStPt->threadsLinkedListEntr->prevTrdMsgStPt;
    newTrdMsgStPt->nextTrdMsgStPt = trdsPolMsgStPt->threadsLinkedListEntr;
    // 更新线程池
    trdsPolMsgStPt->threadsLinkedListEntr->prevTrdMsgStPt = newTrdMsgStPt;
    trdsPolMsgStPt->threadsLinkedListEntr->prevTrdMsgStPt->nextTrdMsgStPt = newTrdMsgStPt;
    trdsPolMsgStPt->activeThreadsCot ++;
}

/**
 * @brief       从链表中移除线程信息
 * @details     从线程链表的尾部移除一个线程信息
 * 
 * @param[in]   trdsPolMsgStPt 线程池指针
 * 
 * @note        此函数假设调用者已持有线程池锁
 */
static inline void removeThreadMsg (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt /**< 线程池信息地址 */
)
{
    // 表尾线程信息地址
    ThreadMsg_st_pt tailTrdMsgStPt;

    // 初始化表尾线程信息地址
    tailTrdMsgStPt = trdsPolMsgStPt->threadsLinkedListEntr->prevTrdMsgStPt;

    // 更新线程池
    trdsPolMsgStPt->threadsLinkedListEntr->prevTrdMsgStPt = tailTrdMsgStPt->prevTrdMsgStPt;
    tailTrdMsgStPt->prevTrdMsgStPt->nextTrdMsgStPt = trdsPolMsgStPt->threadsLinkedListEntr;
    trdsPolMsgStPt->activeThreadsCot --;
    // 更新表尾线程信息
    if (trdsPolMsgStPt->shutDown == false)
    {
        // 线程未启动销毁
        // 主动取消线程
        pthread_cancel(tailTrdMsgStPt->tid);
    }
    else 
    {
        // 线程启动销毁
        // 接合退出的线程
        pthread_join(tailTrdMsgStPt->tid, NULL);
    }
    tailTrdMsgStPt->prevTrdMsgStPt = tailTrdMsgStPt;
    tailTrdMsgStPt->nextTrdMsgStPt = tailTrdMsgStPt;

    // 释放表尾线程信息内存
    free(tailTrdMsgStPt);
}

/**
 * @brief       批量插入新线程信息
 * @details     创建并插入指定数量的新线程到线程池
 * 
 * @param[in]   trdsPolMsgStPt 线程池指针
 * @param[in]   newTrdMSgsCot  要添加的新线程数量
 * 
 * @note        此函数假设调用者已持有线程池锁
 */
static inline void insertSomeNewThreadMsgs (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt,    /**< 线程池信息地址 */
    int newTrdMSgsCot                       /**< 新线程信息量 */
)
{
    for (int i = 0; i < newTrdMSgsCot; i ++)
    {
        // 新线程信息地址
        ThreadMsg_st_pt newTrdMsgStPt;
        // 获取新线程信息
        newTrdMsgStPt = getNewThreadMsg(trdsPolMsgStPt);
        // 插入新线程信息
        insertNewThreadMsg(trdsPolMsgStPt, newTrdMsgStPt);
    }
}

/**
 * @brief       创建新的线程池
 * 
 * @param[in]   orgActiveThreadsCot    初始活跃线程数量
 * @param[in]   maxWaitingTasksCot     最大等待任务数量
 * @param[in]   maxActiveThreadsCot    最大活跃线程数量
 * 
 * @return      成功返回线程池指针，失败返回NULL
 */
ThreadsPoolMsg_st_pt getNewThreadsPoolMsg (
    int orgActiveThreadsCot,                /**< 初始活跃线程量 */
    int maxWaitingTasksCot,                 /**< 最大等待任务量 */
    int maxActiveThreadsCot                 /**< 最大活跃线程量 */
)
{
    // 新线程池信息地址
    ThreadsPoolMsg_st_pt newTrdsPolMsgStPt;

    // 分配新线程池信息地址内存
    newTrdsPolMsgStPt = malloc(sizeof(ThreadsPoolMsg_st));

    // 初始化新线程池信息
    pthread_mutex_init(&newTrdsPolMsgStPt->mtxUn, NULL);
    pthread_cond_init(&newTrdsPolMsgStPt->codUn, NULL);
    newTrdsPolMsgStPt->shutDown = false;
    newTrdsPolMsgStPt->waitingTasksCot = 0;
    newTrdsPolMsgStPt->activeThreadsCot = 0;
    newTrdsPolMsgStPt->maxWaitingTasksCot = maxWaitingTasksCot;
    newTrdsPolMsgStPt->maxActiveThreadsCot = maxActiveThreadsCot;
    newTrdsPolMsgStPt->tasksLinkedQueueEntr = getNewTaskMsg(NULL, NULL);
    newTrdsPolMsgStPt->threadsLinkedListEntr = getNewThreadMsg(NULL);
    insertSomeNewThreadMsgs(newTrdsPolMsgStPt, orgActiveThreadsCot);

    return newTrdsPolMsgStPt;
}

/**
 * @brief       添加新任务到线程池
 */
int addNewTask (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt,    /**< 线程池信息地址 */
    void* (* handleFuncPt)(void* arg),      /**< 处理函数地址 */
    void* handleFuncArg                     /**< 处理函数参数 */    
)
{
    /* +++++++++++++++++++ 压栈预清理函数并加锁 +++++++++++++++++++ */
    READY_CLEAN_UP_AND_LOCK(cleanUpHandle, &trdsPolMsgStPt->mtxUn);
    /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
    if (trdsPolMsgStPt->waitingTasksCot >= trdsPolMsgStPt->maxWaitingTasksCot)
    {
        fprintf(stderr, "等待任务量过多，无法添加。\n");
        return -1;
    }

    // 新任务信息地址
    TaskMsg_st_pt newTaskMsgStPt;

    // 获取新任务信息
    newTaskMsgStPt = getNewTaskMsg(handleFuncPt, handleFuncArg);

    // 入队新任务信息
    inqueueNewTaskMsg(trdsPolMsgStPt, newTaskMsgStPt);
    /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
    UNLOCK_AND_CANCEL_CLEAN_UP(&trdsPolMsgStPt->mtxUn);
    /* +++++++++++++++++++ 解锁并出栈预清理函数 +++++++++++++++++++ */
    // 唤醒所有等待中的线程，通知新任务可执行
    pthread_cond_broadcast(&trdsPolMsgStPt->codUn);

    return 0;
}

/**
 * @brief       从线程池中移除指定任务
 */
int reduceTask (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt,    /**< 线程池地址 */
    void* (* destHandleFuncPt)(void* arg)   /**< 目标处理函数地址 */   
)
{
    /* +++++++++++++++++++ 压栈预清理函数并加锁 +++++++++++++++++++ */
    READY_CLEAN_UP_AND_LOCK(cleanUpHandle, &trdsPolMsgStPt->mtxUn);
    /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
    if (trdsPolMsgStPt->waitingTasksCot <= 0)
    {
        fprintf(stderr, "无等待任务，无法减少。\n");
        return -1;        
    }

    removeDestTaskMsg(trdsPolMsgStPt, destHandleFuncPt);
    /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
    UNLOCK_AND_CANCEL_CLEAN_UP(&trdsPolMsgStPt->mtxUn);
    /* +++++++++++++++++++ 解锁并出栈预清理函数 +++++++++++++++++++ */

    return 0;
}

/**
 * @brief       向线程池中添加新线程
 */
int addThread (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt /**< 线程池信息地址 */
)
{
    /* +++++++++++++++++++ 压栈预清理函数并加锁 +++++++++++++++++++ */
    READY_CLEAN_UP_AND_LOCK(cleanUpHandle, &trdsPolMsgStPt->mtxUn);
    /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
    if (trdsPolMsgStPt->activeThreadsCot >= trdsPolMsgStPt->maxActiveThreadsCot)
    {
        fprintf(stderr, "活跃线程量过多，无法添加。\n");
        return -1;        
    }

    // 新线程信息地址
    ThreadMsg_st_pt newTrdMsgStPt;

    // 获取新线程信息
    newTrdMsgStPt = getNewThreadMsg(trdsPolMsgStPt);
    // 插入新线程
    insertNewThreadMsg(trdsPolMsgStPt, newTrdMsgStPt);
    /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
    UNLOCK_AND_CANCEL_CLEAN_UP(&trdsPolMsgStPt->mtxUn);
    /* +++++++++++++++++++ 解锁并出栈预清理函数 +++++++++++++++++++ */

    return 0;    
}

/**
 * @brief       从线程池中移除线程
 */
int reduceThread (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt /**< 线程池信息地址 */
)
{
    /* +++++++++++++++++++ 压栈预清理函数并加锁 +++++++++++++++++++ */
    READY_CLEAN_UP_AND_LOCK(cleanUpHandle, &trdsPolMsgStPt->mtxUn);
    /* ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ */
    if (trdsPolMsgStPt->activeThreadsCot <= 1)
    {
        fprintf(stderr, "只有一个活跃线程，无法减少。\n");
        return -1;        
    }

    removeThreadMsg(trdsPolMsgStPt);
    /* ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ */
    UNLOCK_AND_CANCEL_CLEAN_UP(&trdsPolMsgStPt->mtxUn);
    /* +++++++++++++++++++ 解锁并出栈预清理函数 +++++++++++++++++++ */

    return 0;        
}

/**
 * @brief       销毁线程信息链表
 * @details     清理所有线程资源，等待线程退出
 * 
 * @param[in]   trdsPolMsgStPt 线程池指针
 */
static inline void destroyThreadMsgsLinkedList (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt /**< 线程池信息地址 */
)
{    
    // 唤醒所有等待新任务的线程
    pthread_cond_broadcast(&trdsPolMsgStPt->codUn);
    while (trdsPolMsgStPt->activeThreadsCot > 0)
    {
        // 存在线程信息
        // 删除线程信息
        removeThreadMsg(trdsPolMsgStPt);
    }    
    // 释放线程链表入口内存
    free(trdsPolMsgStPt->threadsLinkedListEntr);
}

/**
 * @brief       销毁任务信息队列
 * @details     清理所有未执行的任务资源
 * 
 * @param[in]   trdsPolMsgStPt 线程池指针
 */
static inline void destroyTaskMsgsLinkedQueue (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt /**< 线程池信息地址 */    
)
{
    // 任务信息地址
    TaskMsg_st_pt taskMsgStPt;

    while (trdsPolMsgStPt->waitingTasksCot > 0)
    {
        // 获取队头任务信息
        taskMsgStPt = dequeueTaskMsg(trdsPolMsgStPt);
        // 释放队头任务信息内存
        free (taskMsgStPt);
    }    
    // 释放任务链队入口内存
    free(trdsPolMsgStPt->tasksLinkedQueueEntr);
}

/**
 * @brief       销毁线程池
 */
void destroyThreadsPoolMsg (
    ThreadsPoolMsg_st_pt trdsPolMsgStPt /**< 线程池信息地址 */
)
{
    // 启动线程池销毁
    trdsPolMsgStPt->shutDown = true;
    // 销毁线程信息链表
    destroyThreadMsgsLinkedList(trdsPolMsgStPt);
    // 销毁任务信息链队
    destroyTaskMsgsLinkedQueue(trdsPolMsgStPt);
    // 销毁互斥锁
    pthread_mutex_destroy(&trdsPolMsgStPt->mtxUn);
    // 销毁条件量
    pthread_cond_destroy(&trdsPolMsgStPt->codUn);
    // 释放线程池信息内存
    free(trdsPolMsgStPt);
}

#endif